using System.Web.UI;
using System.Web.UI.WebControls;
using System;

namespace PropertyExpression.TypedDataBinding.Web
{
    public class RepeaterBinder<TData> : CollectionBinder<TData, Repeater>
    {
        protected override bool IsDataContainer(Control control)
        {
            return control is RepeaterItem;
        }

        protected override BaseControlWrapper CreateBaseControlWrapper(Repeater control)
        {
            return new BaseControlWrapperImpl(control);
        }

        private class BaseControlWrapperImpl : BaseControlWrapper
        {
            private readonly Repeater repeater;
            public BaseControlWrapperImpl(Repeater repeater)
            {
                this.repeater = repeater;
            }

            public override event Action<IBaseControlItemEventArgs> ItemDataBound
            {
                add
                {
                    AddItemDataBoundHandler(value, () => repeater.ItemDataBound += repeater_ItemDataBound);
                }
                remove
                {
                    RemoveItemDataBoundHandler(value, () => repeater.ItemDataBound -= repeater_ItemDataBound);
                }
            }

            private void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
            {
                ItemDataBoundAction(new BaseControlItemEventArgs(e));
            }

            public override event Action<IBaseControlItemEventArgs> ItemCreated
            {
                add
                {
                    AddItemCreatedHandler(value, () => repeater.ItemCreated += repeater_ItemCreated);
                }
                remove
                {
                    RemoveItemCreatedHandler(value, () => repeater.ItemCreated -= repeater_ItemCreated);
                }
            }

            private void repeater_ItemCreated(object sender, RepeaterItemEventArgs e)
            {
                ItemCreatedAction(new BaseControlItemEventArgs(e));
            }

            private class BaseControlItemEventArgs : IBaseControlItemEventArgs
            {
                private readonly RepeaterItemEventArgs repeaterItemEventArgs;
                public BaseControlItemEventArgs(RepeaterItemEventArgs repeaterItemEventArgs)
                {
                    this.repeaterItemEventArgs = repeaterItemEventArgs;
                }

                public Control Item
                {
                    get { return repeaterItemEventArgs.Item; }
                }

                public object DataItem
                {
                    get { return repeaterItemEventArgs.Item.DataItem; }
                }

                public int ItemIndex
                {
                    get { return repeaterItemEventArgs.Item.ItemIndex; }
                }
            }

            public override object DataSource
            {
                set { repeater.DataSource = value; }
            }

            public override void DataBind()
            {
                repeater.DataBind();
            }
        }
    }
}